package com.ctsi.security.manager.impl;

import com.ctsi.commons.event.BaseEvent;
import com.ctsi.commons.event.EventPublisherMan;
import com.ctsi.commons.util.UtilValidate;
import com.ctsi.commons.util.cache.CommUtilCache;
import com.ctsi.commons.util.collections.UtilCollection;
import com.ctsi.framework.common.startrun.ComponentFactory;
import com.ctsi.organise.common.api.OrganiseFactoryBean;
import com.ctsi.organise.common.api.PersonServiceProxy;
import com.ctsi.organise.common.api.UserLoginServiceProxy;
import com.ctsi.organise.common.model.Person;
import com.ctsi.organise.common.model.UserLogin;
import com.ctsi.security.*;
import com.ctsi.security.domain.*;
import com.ctsi.security.exception.ParamNotValideException;
import com.ctsi.security.service.DataObjectService;
import com.ctsi.security.service.RoleSecurityService;
import com.ctsi.security.service.SecRelateRoleService;
import com.ctsi.security.service.SecurityImplDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
/**
 * 用来实现权限管理的外部接口
 *
 * @author zhangjw
 *
 */
@Service("iSecurity")
public class SecurityImpl implements ISecurity, I_SecurityService {
	private static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(SecurityImpl.class);
	/**
	 * 权限管理输入接口
	 */
	public static final String ACTIONALL = "_ALL";
	@Autowired
	private SecRelateRoleService secRelateRoleService;
    @Autowired
	private SecurityImplDao securityImplDao;

	private Map<String, FetchObjIds> objIds;
    @Autowired
	private RoleSecurityService roleSecurityService;
    @Autowired
	private volatile PersonServiceProxy personService;
    @Autowired
	private volatile UserLoginServiceProxy userLoginService;
    @Autowired
	private PermissionTypeSer permissionTypeService;
    @Autowired
	private PermissionRole sroleService;
    @Autowired
	private PermissionSer permissionService;
    @Autowired
	private DataObjectService dataObjectservice;
	
	/**
	 * 发布事件
	 */
	private static EventPublisherMan publisherMan;
	
	public static EventPublisherMan getPublisherMan() {
		if(publisherMan==null)
		{
			publisherMan=EventPublisherMan.getEventPublisherMan();
		}
		return publisherMan;
	}

	public static void setPublisherMan(EventPublisherMan publisherMan) {
		SecurityImpl.publisherMan = publisherMan;
	}

	private static void publishEvent(Map<String,Object> map  ) {
		BaseEvent o=new BaseEvent(ComponentFactory.getBean("iSecurity"),"clearRomoteSecurityCache",map);
		getPublisherMan().getEventPublisher().publishEvent(o );
	}

	/**
	 * 缓存用户的角色
	 * 
	 * key user 用户的loginId
	 * 
	 * value List<roles> 用户的角色
	 * 
	 */
	// private static final CommUtilCache<String, List<String>> cacheUserRole = new CommUtilCache<String, List<String>>(
	// "user.role");
	protected static final CommUtilCache<String, SecurityPersonBean> cacheUserRole = new CommUtilCache<String, SecurityPersonBean>("user.role");

	protected static final CommUtilCache<String, CacheRole> cacheRole = new CommUtilCache<String, CacheRole>("role.cacheRole");

	protected static final CommUtilCache<String, DataObjectType> dotypeCategory = new CommUtilCache<String, DataObjectType>("doType.category");

	protected static final CommUtilCache<String, List<UserDataObject>> userResObject = new CommUtilCache<String, List<UserDataObject>>("userId.userResObject");

	protected static final CommUtilCache<String, List<DataObject>> dataObjects_ = new CommUtilCache<String, List<DataObject>>("typeId.dataObjects");
	/**
	 * 缓存人员权限
	 */
	protected static final CommUtilCache<String, List<RolePermission>> personpermision = new CommUtilCache<String, List<RolePermission>>("person.permision");
	/**
	 * 缓存权限和类型 <permission,type>
	 */
	protected static final CommUtilCache<String, String> permisiontypecache = new CommUtilCache<String, String>("permision.type");

	/**
	 * 获取用户权限相关的角色
	 * 
	 * @param typeid
	 * @return
	 */
	public static final void clearDataObjectCache(final String typeid) {
		logger.info("清除dataobject缓存 类型 {}", typeid);
		if (UtilValidate.isEmpty(typeid)) {
			dataObjects_.clear();
		} else {
			dataObjects_.remove(typeid);
		}
		PermisionTypeTreeCache.clear();
		
		//发布事件
		Map<String,Object> map = new HashMap<String, Object>();
		map.put("typeid", typeid);
		
		SecurityImpl.publishEvent(map);
		
	}
    @Override
	public List<String> getSecurityRoles(final String userLoginId) {

		return UtilCollection.unmodifiableList(this.getCacheUserRole(userLoginId));

	}
    @Override
	public Permission findByPermission(final String permissionId) {
		return permissionService.findByPermission(permissionId);
	}

	/**
	 * 是否属于某个权限组
	 * 
	 * @param userLoginId
	 * @param roleId
	 * @return
	 */
	@Override
	public boolean isSecurityRole(String userLoginId, String roleId) {
		if (UtilValidate.isEmpty(userLoginId)) {
			return false;
		}
		if (Collections.binarySearch(getCacheUserRole(userLoginId), roleId) > -1) {
			return true;
		}
		return false;
		// return this.getCacheUserRole(userLoginId).contains(roleId.trim());
	}

	/**
	 * 角色是否具有指定的功能权限
	 * 
	 * @param roleId
	 * @param permissionId
	 * @return
	 */
	@Override
	public boolean rolePermissionExists(String roleId, String permissionId) {
		if (Collections.binarySearch(getCachePermissionIds(roleId), permissionId) > -1) {
			return true;
		}
		return false;
		// return this.getCachePermissionIds(roleId).contains(permissionId);
	}

	/**
	 * 角色是否具有指定数据对象的权限 gyz add/2008-7-21
	 * 
	 * @param roleId
	 * @param action
	 * @param dataObectType
	 * @param dataObjectId
	 * @return
	 */
	@Override
	public boolean roleDataPermissionExists(final String roleId,final  String action,final  String dataObectType,final  String dataObjectId) {
		return this.hasRoleDataObjectId(roleId, action, dataObectType, dataObjectId);
	}

	private boolean hasPermissionOld(String userLoginId, String permissionId) {
		if (UtilValidate.isEmpty(permissionId)) {
			logger.warn("permissionId is null,return false");
			return false;
		}
		if (UtilValidate.isEmpty(userLoginId)) {
			logger.warn("UsloginId is null,return false");
			return false;
		}

		List<String> listRoleId = this.getCacheUserRole(userLoginId);
		for (String roleId : listRoleId) {
			if (Collections.binarySearch(getCachePermissionIds(roleId), permissionId) > -1) {
				return true;
			}
		}
		List<RolePermission> rlist = getPersonPermissionFromCache(userLoginId);
		for (RolePermission rp : rlist) {
			if (permissionId.equals(rp.getPermissionId())) {
				return true;
			}
		}
		logger.debug("登录用户{} 不包含权限 {}", userLoginId, permissionId);
		return false;
	}

	/**
	 * 用户是否有某个功能权限
	 * 
	 * 根据用户取用户所有的角色
	 * @param userLoginId
	 * 	 *            用户登录id
	 * @param permissionId
	 *            permission id
	 *
	 * @return
	 */

	public boolean hasPermission(String userLoginId, String permissionId) {
		if (hasPermissionOld(userLoginId, permissionId)) {
			return true;
		}
		if (UtilValidate.isEmpty(permissionId)) {
			logger.warn("permissionId is null,return false");
			return false;
		}
		if (UtilValidate.isEmpty(userLoginId)) {
			logger.warn("UsloginId is null,return false");
			return false;
		}
		// if (userLoginId.length()>20)
		// {
		// Thread.dumpStack();
		// }
		String type = null;
		if (permisiontypecache.containsKey(permissionId)) {
			type = permisiontypecache.get(permissionId);
		} else {
			Permission perm = permissionService.findByPermission(permissionId);
			if (perm == null) {
				permisiontypecache.put(permissionId, null);
			} else {
				permisiontypecache.put(permissionId, perm.getPermissionTypeId());
				type = perm.getPermissionTypeId();
			}
		}
		if (UtilValidate.isEmpty(type)) {
			return false;
		} else {
			return hasPermissionWithType(userLoginId, type, permissionId);
		}

	}
    @Override
	public boolean hasPermissionWithType(final String userLoginId,final  String type,final  String permissionId) {
		if (UtilValidate.isEmpty(type)) {
			return hasPermission(userLoginId, permissionId);
		}
		// 获取所有上级节点类型
		String allpath = PermisionTypeTreeCache.getInstance().getPermisionPath(type);
		if (allpath == null) {
			logger.warn("类型 {} 不存在上级类型 ", type);
			PermisionTypeTreeCache.getInstance().printCache();
			return false;
		}
		// 获取所有权限
		Set<RolePermission> set = getPersonRolePermission(userLoginId);
		for (RolePermission rolePermission : set) {
			String permtype = rolePermission.getPermisionType();
			// 旧类型不做匹配
			if (UtilValidate.isEmpty(permtype) || "def".equalsIgnoreCase(permtype)) {
				continue;
			}
			if (permtype.equals(allpath)) {
				if (rolePermission.getPermissionId().equals(ISecurity.PERMISION_ALLPERMISION) || rolePermission.getPermissionId().equals(permissionId)) {
					return true;
				}
				// 拥有当前类型的祖宗类型
			} else if (allpath.startsWith(permtype)) {
				if (rolePermission.hasLower() && (rolePermission.getPermissionId().equals(ISecurity.PERMISION_ALLPERMISION) || rolePermission.getPermissionId().equals(permissionId))) {
					return true;
				}
			}
		}
		return false;
	}

	private List<RolePermission> getPersonPermissionFromCache(String userLoginId) {
		// 如果包含登录人 不管是否为空都返回
		if (personpermision.containsKey(userLoginId)) {
			return personpermision.get(userLoginId);
		}
		List<RolePermission> list = roleSecurityService.findPersenPermision(userLoginId);
		personpermision.put(userLoginId, list);
		return list;

	}

	/**
	 * 清除人员权限
	 * 
	 * @param loginId
	 */
	public static void clearPersonPermision(final String loginId) {
		if (UtilValidate.isEmpty(loginId)) {
			personpermision.clear();
		} else {
			personpermision.remove(loginId);
		}
		
		//发布事件
				Map<String,Object> map = new HashMap<String, Object>();
				map.put("userloginId", loginId);
		 
				SecurityImpl.publishEvent(map);
	}

	public static void clearPermisiontypecache(final String permisionId) {
		if (UtilValidate.isEmpty(permisionId)) {
			permisiontypecache.clear();
		} else {
			permisiontypecache.remove(permisionId);
		}
		
		//发布事件
		Map<String,Object> map = new HashMap<String, Object>();
		map.put("permisionId", permisionId);
 
		SecurityImpl.publishEvent(map);

	}
    @Override
	public Set<RolePermission> getPersonRolePermission(final String userLoginId) {
		List<String> roleids = this.getCacheUserRole(userLoginId);
		Set<RolePermission> set = new HashSet<RolePermission>();
		if (roleids != null) {
			for (String roleId : roleids) {
				CacheRole cacheRole = getCacheRole(roleId);
				List<RolePermission> temp = cacheRole.getRolePermissions();
				set.addAll(temp);
			}
		}
		set.addAll(getPersonPermissionFromCache(userLoginId));
		return set;
	}
    @Override
	public boolean hasPerm(final String userLoginId,final  String permissionId) {
		return hasPermission(userLoginId, permissionId);
	}

	private List<String> getCachePermissionIds(String roleId) {
		List<String> result;
		CacheRole tempCacheRole = cacheRole.get(roleId);
		if (tempCacheRole != null) {
			result = tempCacheRole.getPermissionIds();
		} else {
			cacheRole.put(roleId, initCacheRole(roleId));
			result = cacheRole.get(roleId).getPermissionIds();
		}
		logger.debug("角色 {},包含权限 {}", roleId, result);
		return result;
	}

	/**
	 * 上面的为接口方法
	 */

	/**
	 * gyz add/2008-7-21
	 * 
	 * @param roleId
	 * @param action
	 * @param dataObectType
	 * @param dataObjectId
	 * @return
	 */
	private boolean hasRoleDataObjectId(String roleId, String action, String dataObectType, String dataObjectId) {
		if (UtilValidate.isEmpty(roleId) || UtilValidate.isEmpty(dataObectType) || UtilValidate.isEmpty(dataObjectId)) {
			throw new ParamNotValideException("参数不合法！");
		}
		boolean result = false;
		action = getActionValue(action);
		result = getRoleDoIdData(roleId, action, dataObectType, dataObjectId, result);
		return result;
	}

	private boolean getRoleDoIdData(String roleId, String action, String dataObectType, String dataObjectId, boolean result) {
		CacheRole roleCache = cacheRole.get(roleId);
		if (roleCache != null) {
			List<RoleDataObject> items = roleCache.getDataObjectIds();
			Set<String> dataObjectIds = getRoleDataTypeActionIds(items, dataObectType, action, true);
			result = dataObjectIds.contains(dataObjectId);
		} else {
			int count = 0;
			Map<String, Object> map = new LinkedHashMap<String, Object>();
			map.put("roleId", roleId);
			map.put("action", action);
			map.put("dataObjectTypeId", dataObectType);
			map.put("dataObjectId", dataObjectId);
			// count=(Integer)
			// ibatisDao.getSqlMapClientTemplate().queryForObject(SecurityImpl.class.getName()+".selDataObjectId",map);
			count = securityImplDao.getRoleDoIdData(map);
			if (count > 0) {// 有数据权限
				result = true;
			}
		}
		return result;
	}

	private SecurityPersonBean getCasheSecurityPersonBean(String userLoginId) {
		SecurityPersonBean securityPersonBean = cacheUserRole.get(userLoginId);
		if (securityPersonBean == null && !cacheUserRole.containsKey(userLoginId)) {
			List<String> result = secRelateRoleService.getRoleByLoginId(userLoginId);
			Integer securityLevel = Integer.valueOf(0);
			UserLogin userLogin = getUserLoginService().findById(userLoginId);

			if (userLogin != null && UtilValidate.isNotEmpty(userLogin.getPartyId())) {
				if (!userLogin.getPartyId().startsWith(UserLoginServiceProxy.outerPerson)) {
					Person person = getPersonService().findPersonById(userLogin.getPartyId());
					if (person != null) {
						securityLevel = person.getSecurityLevel();
					}
				}
			}
			securityPersonBean = new SecurityPersonBean(result, securityLevel);
			cacheUserRole.put(userLoginId, securityPersonBean);

		}
		return securityPersonBean;
	}

	/**
	 * 从缓存中得到用户的角色
	 * 
	 * @param userLoginId
	 * @return
	 */
	protected List<String> getCacheUserRole(String userLoginId) {

		SecurityPersonBean securityPersonBean = getCasheSecurityPersonBean(userLoginId);
		logger.debug("登录用户 {},包含角色 {}", userLoginId, securityPersonBean.getRoleList());
		return securityPersonBean.getRoleList();
	}

	/**
	 * 删除缓存中某用户对应的角色
	 * 
	 * @param userLoginId
	 */
	public static void removeCacheUserRoles(String userLoginId) {
		logger.info("清除LoginId:{}的缓存", userLoginId);
		if (UtilValidate.isEmpty(userLoginId)) {
			logger.info("LoginId is null");
		} else {
			cacheUserRole.remove(userLoginId);
		}
		//发布事件
				Map<String,Object> map = new HashMap<String, Object>();
				map.put("userLoginId", userLoginId);
 
				SecurityImpl.publishEvent(map);
	}

	public SecRelateRoleService getSecRelateRoleService() {
		return secRelateRoleService;
	}

	public void setSecRelateRoleService(SecRelateRoleService secRelateRoleService) {
		this.secRelateRoleService = secRelateRoleService;
	}

	/**
	 * 获取用户有权限的数据对象id
	 */
    @Override
	public List<String> getDataObjectIds(final String userLoginId,final  String doTypeId, String action) {
		if (UtilValidate.isEmpty(doTypeId) || UtilValidate.isEmpty(userLoginId)) {
			throw new ParamNotValideException("参数不合法!");
		}
		action = getActionValue(action);

		List<String> result = new ArrayList<String>(getAllCacheDoIdsData(userLoginId, doTypeId, action));

		return result;
	}
    @Override
	public Set<String> findDataObjectIds(final String userLoginId,final  String doTypeId, String action) {
		if (UtilValidate.isEmpty(doTypeId) || UtilValidate.isEmpty(userLoginId)) {
			throw new ParamNotValideException("参数不合法!");
		}
		action = getActionValue(action);
		return Collections.unmodifiableSet(getAllCacheDoIdsData(userLoginId, doTypeId, action));
	}

	private Set<String> getAllCacheDoIdsData(final String userLoginId, String doTypeId, String action) {
		// 判断类型
		DataObjectType dot = getCachedoType(doTypeId);
		String category;
		if (dot != null) {
			category = dot.getCategory();
		} else {
			category = "0";//此处可能有问题zhangjw 2014-9-27
		}
		Set<String> result;
		if (category == null || dot.isInner()) {
			result = getCacheDoIdsData(userLoginId, doTypeId, action);
		} else {
			if (getObjIds().containsKey(category)) {
				FetchObjIds fetchObjIds = getObjIds().get(category);
				if (fetchObjIds.isUserRole()) {
					result = getCacheDoIdsData(userLoginId, doTypeId, action);
				} else {
					result = fetchObjIds.getDataObjectIdsByCache(userLoginId, doTypeId, action);
				}
			} else {
				result = new HashSet<String>(0);
			}
		}

		return result;

	}

	public DataObjectType getCachedoType(String doTypeId) {
		DataObjectType result = null;
		DataObjectType dataObjectType = dotypeCategory.get(doTypeId);
		if (dataObjectType != null) {
			result = dataObjectType;
		}
		if (result == null) {// 取数据库
			// List<DataObjectType>
			// resultList=ibatisDao.getSqlMapClientTemplate().queryForList(SecurityImpl.class.getName()+".queryType",doTypeId);
			List<DataObjectType> resultList = securityImplDao.getdoType(doTypeId);
			if (UtilValidate.isNotEmpty(resultList)) {
				result = resultList.get(0);
			} else {
				logger.warn("类型{}没有对应的类别", doTypeId);
			}
			// 放入缓存
			dotypeCategory.put(doTypeId, UtilValidate.isNotEmpty(resultList) ? resultList.get(0) : null);
		}
		return result;
	}

	/**
	 * 不可修改RoleDataObject中的内容
	 * 
	 * @param doTypeId
	 * @param roleId
	 * @return
	 */
	private List<RoleDataObject> getRoleDataObjectByRoleId(String roleId, String doTypeId) {
		CacheRole crOk = cacheRole.get(roleId);
		if (crOk == null) {
			synchronized (this.getClass()) {
				if (cacheRole.get(roleId) == null) {
					crOk = initCacheRole(roleId);
					cacheRole.put(roleId, crOk);
				}
			}
		}
		if (crOk != null) {
			return  crOk.getDataObjectIds() ;

		} else {

			logger.warn("缓存错误！roleId:{} doTypeId:{}",roleId,doTypeId);
		}
		return new ArrayList<RoleDataObject>(0);

	}

	/**
	 * 通过登陆ID和数据对象ID 获取角色数据对象
	 * @param userLoginId
	 * @param doTypeId
	 * @return
	 */
	private List<RoleDataObject> getRoleDataObjectByLoginId(String userLoginId, String doTypeId) {

		List<String> roleIds = getCacheUserRole(userLoginId);
		List<RoleDataObject> list = new ArrayList<RoleDataObject>(64);
		for (String roleId : roleIds) {
			list.addAll(getRoleDataObjectByRoleId(roleId, doTypeId));
		}
		return list;
	}

	/**
	 * 获取有权限的数据对象id
	 * 
	 * @param userLoginId
	 * @param doTypeId
	 * @param action
	 * @return
	 */
	private Set<String> getCacheDoIdsData(String userLoginId, String doTypeId, String action) {
		// 判断参数
		if (UtilValidate.isEmpty(userLoginId) || UtilValidate.isEmpty(doTypeId)) {
			throw new ParamNotValideException("参数不合法，请检查!");
		}

		action = getActionValue(action);

		List<RoleDataObject> roleDataIds = getRoleDataObjectByLoginId(userLoginId, doTypeId);

		return getRoleDataTypeActionIds(roleDataIds, doTypeId, action, true);

	}

	private void getAllChild(Set<String> set, String typeId, String dataObjectId) {
		List<DataObject> list = queryDataObject(typeId, dataObjectId);
		for (DataObject dataObject : list) {
			set.add(dataObject.getDataObjectId());
			getAllChild(set, typeId, dataObject.getDataObjectId());
		}
	}

	private List<DataObject> queryDataObject(String typeId, String parent) {
		DataObjectType dot = getCachedoType(typeId);
		if (dot == null || dot.isInner()) {
			return queryInnerDataObject(typeId, parent);
		}
		FetchObjIds fetchObjIds = dot.getFetchObjIds();
		if (fetchObjIds.isUserRole()) {
			return fetchObjIds.queryDataObject(typeId, parent);
		} else {
			logger.info("扩展的独立管理用户类型返回空");
			return new ArrayList<DataObject>(0);
		}
	}

	private List<DataObject> queryInnerDataObject(String typeId, String parent) {
		List<DataObject> list = queryInnerDataObjectByTypeId(typeId);
		List<DataObject> returnlist = new ArrayList<DataObject>();
		for (DataObject dataObject : list) {
			if (UtilValidate.isNotEmpty(dataObject.getParent()) && dataObject.getParent().equals(parent)) {
				returnlist.add(dataObject);
			}
		}
		return returnlist;
	}

	private List<DataObject> queryInnerDataObjectByTypeId(String typeId) {
		List<DataObject> list = dataObjects_.get(typeId);
		if (list == null) {
			list = roleSecurityService.queryDataObject(typeId);
			dataObjects_.put(typeId, list);
		}
		return list;
	}

	private DataObject findDataObjectById(String id, String typeId) {
		List<DataObject> list = queryInnerDataObjectByTypeId(typeId);
		for (DataObject dataObject : list) {
			if (dataObject.getDataObjectId().equals(id)) {
				return dataObject;
			}
		}
		return null;

	}

	/**
	 * 获取角色在某个数据类型上某个操作的数据对象id
	 * @param roleDataIds
	 * @param doTypeId
	 * @param action
	 * @param isSearchChild
	 * @return
	 */
	private Set<String> getRoleDataTypeActionIds(List<RoleDataObject> roleDataIds, String doTypeId, String action, boolean isSearchChild) {
		long start = 0;
		if (logger.isInfoEnabled())
			start = System.currentTimeMillis();
		Set<String> result = new HashSet<>();
		Set<String> allrole = new HashSet<>();
		for (RoleDataObject item : roleDataIds) {
			if (item.getDataObjectTypeId().equals(doTypeId) && item.getDataObjectAction().equals(action)) {
				result.add(item.getDataObjectId());
			}

			if (item.getDataObjectTypeId().equals(doTypeId) && item.getDataObjectAction().equals(RoleDataObject.LOWALL)) {
				result.add(item.getDataObjectId());
				allrole.add(item.getDataObjectId());
			}
			if (item.getDataObjectId().endsWith(RoleDataObject.ALL) && (item.getDataObjectAction().equals(RoleDataObject.LOWALL) || item.getDataObjectAction().equals(action))) {
				allrole.add(item.getDataObjectTypeId());
			}
		}
		if (isSearchChild) {
			for (String str : allrole) {
				getAllChild(result, doTypeId, str);
			}
		}
		if (logger.isInfoEnabled())
			logger.info("过滤action耗时 {} ms", System.currentTimeMillis() - start);
		return result;
	}

	/**
	 * 检查登录用户是否对某数据对象为action
	 * 
	 * @param userLoginId
	 * @param action
	 * @param dataObjectId
	 * @return
	 */
	@Override
	public boolean hasUserDataPermission(final String userLoginId, String action,final  String dataObjectTypeId,final  String dataObjectId) {
		if (isForbidden(dataObjectTypeId)) {
			return true;
		}
		if (UtilValidate.isEmpty(userLoginId) || UtilValidate.isEmpty(dataObjectId) || UtilValidate.isEmpty(dataObjectTypeId)) {
			throw new ParamNotValideException("参数不合法!");
		}
		action = getActionValue(action);
		Set<String> dataObjectids = findDataObjectIds(userLoginId, dataObjectTypeId, action);
		return dataObjectids.contains(dataObjectId);

	}

	/**
	 * 判断登录用户是否对数据对象类型控制数据权限
	 * 
	 * @param doTypeId
	 * @return
	 */
	@Override
	public boolean isControl(final String userLoginId,final  String doTypeId, String action) {
		// 流程类型是否禁用数据权限
		if (isForbidden(doTypeId)) {
			return false;
		}
		action = getActionValue(action);

		// 判断参数
		if (UtilValidate.isEmpty(userLoginId) || UtilValidate.isEmpty(doTypeId)) {
			throw new ParamNotValideException("参数不合法，请检查!");
		}
//		action = getActionValue(action);
		List<RoleDataObject> roleDataIds = getRoleDataObjectByLoginId(userLoginId, doTypeId);
		Set<String> result = getRoleDataTypeActionIds(roleDataIds, doTypeId, action, false);

		return !result.contains(doTypeId.concat("ALL"));

	}
    @Override
	public boolean isForbidden(final String doTypeId) {
		DataObjectType dot = getCachedoType(doTypeId);
		Integer flag = 0;
		if (dot != null) {
			flag = dot.getStatus();
		}
		if (flag.intValue() == DataObjectType.FORBIDDEN) {
			return true;
		} else {
			return false;
		}
	}
    @Override
	public Map<String, DataObject> getDataObject(String userLoginId, String doTypeId, String action) {
		if (UtilValidate.isEmpty(doTypeId) || UtilValidate.isEmpty(userLoginId)) {
			throw new ParamNotValideException("参数不合法!");
		}
		action = getActionValue(action);
		Map<String, DataObject> result = new HashMap<String, DataObject>();
		// 根据类型Id找到相应的类型信息
		DataObjectType dot = getCachedoType(doTypeId);
		String category = null;
		if (dot != null) {
			category = dot.getCategory();
		}
		if (category == null || dot.isInner()) {
			Set<String> objectList = this.findDataObjectIds(userLoginId, doTypeId, action);
			for (String id : objectList) {
				DataObject dataObject = findDataObjectById(id, doTypeId);
				if (dataObject != null) {
					result.put(id, dataObject);
				}
			}

		} else {
			FetchObjIds temp = getObjIds().get(category);
			if (temp != null) {
				if (temp.isUserRole()) {
					Set<String> objectList = this.findDataObjectIds(userLoginId, doTypeId, action);
					for (String id : objectList) {
						DataObject dataObject = temp.findDataObjectById(id, doTypeId);
						if (dataObject != null) {
							result.put(id, dataObject);
						}
					}
				} else {
					result = temp.getDataObject(userLoginId, doTypeId, action);
				}

			}
		}

		return result;
	}

	public void setObjIds(Map<String, FetchObjIds> objIds) {
		this.objIds = objIds;

	}

	public Map<String, FetchObjIds> getObjIds() {
		if (UtilValidate.isEmpty(objIds)) {
			synchronized (SecurityImpl.class) {
				if (UtilValidate.isEmpty(objIds)) {
					Map<String, FetchObjIds> objs = new HashMap<String, FetchObjIds>();
					String[] beanNames = ComponentFactory.getApplicationContext().getBeanNamesForType(FetchObjIds.class);
					for (int i = 0; i < beanNames.length; i++) {
						FetchObjIds fetchObjIds = (FetchObjIds) ComponentFactory.getBean(beanNames[i]);
						if(objs.containsKey(fetchObjIds.getKey())){
							logger.warn("duplicate key :{} new  class :{} old class {}",fetchObjIds.getKey(),fetchObjIds.getClass(),objs.get(fetchObjIds.getKey()).getClass());
						}
						objs.put(fetchObjIds.getKey(), fetchObjIds);
					}
					objIds = objs;
				}
			}
		}
		return objIds;
	}

	/**
	 * 取得Action的值
	 * 
	 * @param action
	 * @return
	 */
	private String getActionValue(final String action) {
		String result;// 返回结果
		if (UtilValidate.isNotEmpty(action)) {
			// 判断是否含有-
			int flag = action.lastIndexOf("-");
			if (flag != -1) {
				result = action.substring(flag + 1);
			} else {
				result = action;
			}
		} else {
			logger.warn("所传参数action为空，取默认值SELECT");
			result = "SELECT";
		}
		return result;
	}

	/**
	 * 清空角色的缓存
	 * 
	 * @param roleId
	 */
	public static void removeCacheRole(String roleId) {
		logger.info("清空角色{}对应的缓存！", roleId);
		if (UtilValidate.isEmpty(roleId)) {
			cacheRole.clear();
		} else {
			cacheRole.remove(roleId);
		}
		
		//发布事件
		Map<String,Object> map = new HashMap<String, Object>();
		map.put("roleId", roleId);
 
		SecurityImpl.publishEvent(map);
	}

	/**
	 * 清空数据对象类型缓存
	 * 
	 * @param doTypeId
	 */
	public static void removeCacheDoType(String doTypeId) {
		logger.info("清空数据对象类型{}对应的缓存!", doTypeId);
		dotypeCategory.remove(doTypeId);
		
		//发布事件
				Map<String,Object> map = new HashMap<String, Object>();
				map.put("doTypeId", doTypeId);
 
				SecurityImpl.publishEvent(map);
	}

	/**
	 * 初始化角色缓存对象
	 * 
	 * @param roleId
	 * @return
	 */
	private CacheRole initCacheRole(String roleId) {
		CacheRole cacheRole = new CacheRole(roleId);
		cacheRole.setRoleId(roleId);
		List<String> tempPerms = securityImplDao.getPermissionIds(roleId);
		List<RoleDataObject> tempDoTypes = securityImplDao.getRoleDataObjects(roleId, null);
		List<RolePermission> rolePermisionList = roleSecurityService.findRolePermision(roleId);
		cacheRole.setDataObjectIds(tempDoTypes);
		cacheRole.setPermissionIds(tempPerms);
		cacheRole.setRolePermissions(rolePermisionList);
		return cacheRole;
	}

	private CacheRole getCacheRole(String roleId) {
		CacheRole tempCacheRole = cacheRole.get(roleId);
		if (tempCacheRole == null) {
			tempCacheRole = initCacheRole(roleId);
			cacheRole.put(roleId, tempCacheRole);
		}
		return tempCacheRole;
	}
    @Override
	public List<String> getResourceIds(final String userLoginId,final  String resType, String action) {
		if (UtilValidate.isEmpty(resType) || UtilValidate.isEmpty(userLoginId)) {
			throw new ParamNotValideException("参数不合法!");
		}
		action = getActionValue(action);
		List<String> result = getAllCacheResIdsData(userLoginId, resType, action);
		return UtilCollection.unmodifiableList(result);
	}

	public void addRole(SRole role) {
		sroleService.addRole(role);
	}
    @Override
	public void savePermission(Permission permission) {
		permissionService.savePermission(permission);
	}

	public void saveRolePermission(RolePermission rolePermission) {
		roleSecurityService.saveRolePermission(rolePermission);
	}
    @Override
	public SRole findSRoleById(final String roleId) {
		return sroleService.findSRoleById(roleId);
	}

	private List<String> getAllCacheResIdsData(String userLoginId, String resType, String action) {

		List<String> result = getCacheResIdsData(userLoginId, resType, action);

		// 对结果进行排序
		Collections.sort(result);
		return result;

	}

	private List<String> getCacheResIdsData(String userLoginId, String resType, String action) {
		// 判断参数
		if (UtilValidate.isEmpty(userLoginId) || UtilValidate.isEmpty(resType)) {
			throw new ParamNotValideException("参数不合法，请检查!");
		}
		List<String> result = null;
		action = getActionValue(action);

		boolean flag = userResObject.containsKey(userLoginId);
		if (flag) {
			// founded
			List<UserDataObject> userResIdList = userResObject.get(userLoginId);
			result = getUserResObjByType(userResIdList, resType, action);
		} else {
			// not founded,from database
			List<String> userDataObjectIds = getUserResObject(userLoginId, resType, action);
			// 检查是否为空
			if (UtilValidate.isNotEmpty(userDataObjectIds)) {
				result = userDataObjectIds;
			}
			// 加入缓存
			userResObject.put(userLoginId, securityImplDao.initUserResIds(userLoginId));
		}
		if (result == null) {
			return new ArrayList<String>(0);
		} else {
			return result;
		}

	}

	private List<String> getUserResObjByType(List<UserDataObject> userResIdList, String resType, String action) {
		List<String> result = new ArrayList<String>();
		for (UserDataObject item : userResIdList) {
			if (item.getResTypeId().equals(resType) && (item.getAction().equals(action) || item.getAction().equals(ACTIONALL))) {
				if (!result.contains(item.getResId()))
					result.add(item.getResId());
			}
		}
		return result;
	}

	private List<String> getUserResObject(String userLoginId, String resType, String action) {
		action = getActionValue(action);
		return securityImplDao.getUserResObject(userLoginId, resType, action);
	}
    @Override
	public boolean hasUserResourcePermission(final String userLoginId,final  String resType,final  String action,final  String resId) {
		List<String> resIds = getResourceIds(userLoginId, resType, action);
		return Collections.binarySearch(resIds, resId) > -1 ? true : false;
	}

	public static final void removeUserResIDCache(final String userLoginId) {
		logger.info("清空登录用户{}的数据权限（资源ID）", userLoginId);
		List<UserDataObject> userDataObjects = userResObject.remove(userLoginId);
		if(UtilValidate.isNotEmpty(userDataObjects)){
			Map<String,Object> map = new HashMap<String, Object>();
			map.put("userLoginId", userLoginId);
		 
			SecurityImpl.publishEvent(map);
			logger.info("发布清空登录用户{}的数据权限（资源ID）事件，类型为【clearRomoteSecurityCache】", userLoginId);
		}
	}

	public void setSecurityImplDao(SecurityImplDao securityImplDao) {
		this.securityImplDao = securityImplDao;
	}

	public SecurityImplDao getSecurityImplDao() {
		return securityImplDao;
	}
    @Override
	public boolean hasPermission(List<String> roleIds,final String permissionId) {
		if (UtilValidate.isEmpty(roleIds)) {
			return false;
		}
		for (String roleId : roleIds) {

			if (this.rolePermissionExists(roleId, permissionId)) {
				return true;
			}
		}
		return false;
	}
    @Override
	public boolean hasPermissionInRoles(final List<String> roleIds,final String permissionId) {
		return hasPermission(roleIds, permissionId);
	}

	public List<DataObject> findDataObject(String[] field, Object[] args) {
		return dataObjectservice.findDataObject(field, args);
	}

	public RoleSecurityService getRoleSecurityService() {
		return roleSecurityService;
	}

	public void setRoleSecurityService(RoleSecurityService roleSecurityService) {
		this.roleSecurityService = roleSecurityService;
	}


	public void setSroleService(PermissionRole sroleService) {
		this.sroleService = sroleService;
	}


	public void setPermissionService(PermissionSer permissionService) {
		this.permissionService = permissionService;
	}

	public DataObjectService getDataObjectservice() {
		return dataObjectservice;
	}

	public void setDataObjectservice(DataObjectService dataObjectservice) {
		this.dataObjectservice = dataObjectservice;
	}
    @Override
	public int getSecurityLevel(String userLoginId) {
		SecurityPersonBean securityPersonBean = getCasheSecurityPersonBean(userLoginId);
		return securityPersonBean.getSecurityLevel() == null ? 0 : securityPersonBean.getSecurityLevel();
	}

	public PersonServiceProxy getPersonService() {
		if (personService == null) {
			personService = OrganiseFactoryBean.getInstance().getPersonServiceProxy();
		}
		return personService;
	}

	public void setPersonService(PersonServiceProxy personService) {
		this.personService = personService;
	}

	public UserLoginServiceProxy getUserLoginService() {
		if (userLoginService == null) {
			userLoginService = OrganiseFactoryBean.getInstance().getUserLoginProxy();
		}

		return userLoginService;
	}

	public void setUserLoginService(UserLoginServiceProxy userLoginService) {
		this.userLoginService = userLoginService;
	}

	public PermissionTypeSer getPermissionTypeService() {
		return permissionTypeService;
	}

	public void setPermissionTypeService(PermissionTypeSer permissionTypeService) {
		this.permissionTypeService = permissionTypeService;
	}

	
}
